package com.ciko.code.logic.db;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.text.TextUtils;

import com.ciko.code.annotations.Column;
import com.ciko.code.annotations.Except;
import com.ciko.code.logic.table.ApproverBookInfoTable;
import com.ciko.code.logic.table.SuperTable;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;


/**
 * 联系人数据库
 */
public class ContactsDBHelper extends SQLiteOpenHelper {
    public static final int TYPE_INSERT = 1;
    public static final int TYPE_UPDATE = 2;
    private static ContactsDBHelper myInstance = null;
    public final static String DB = "qy_approver.db";
    // 可读的SQLiteDatabase对象
    private static ThreadLocal<SQLiteDatabase> sqliteDatabaseR = new ThreadLocal<>();
    // 可写的SQLiteDatabase对象
    private static ThreadLocal<SQLiteDatabase> sqliteDatabaseW = new ThreadLocal<>();


    private ContactsDBHelper(Context context) {
        super(context, DB, null, 1);
    }

    private void createTables(SQLiteDatabase db) {
        db.execSQL(ApproverBookInfoTable.getCreateTableSQL());
        db.execSQL(SuperTable.getCreateTableSQL());
    }

    public static ContactsDBHelper getInstance(Context context) {
        if (myInstance == null) {
            myInstance = new ContactsDBHelper(context);
        }
        return myInstance;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        createTables(db);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        try {
            db.beginTransaction();
            switch (newVersion) {
                case 2:
                    update2(db);
            }
            db.setTransactionSuccessful();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            db.endTransaction();
        }
        db.setVersion(1);
    }

    private void update2(SQLiteDatabase db) {

    }

    /**
     * 获得可读的SQLiteDatabase对象
     */
    public synchronized SQLiteDatabase getSqliteDatabaseR() {
        SQLiteDatabase dbR = sqliteDatabaseR.get();
        if (null == dbR || !dbR.isOpen()) {
            dbR = getReadableDatabase();
            sqliteDatabaseR.set(dbR);
        }
        return dbR;
    }

    /**
     * 关闭可读的SQLiteDatabase对象
     */
    public void closeSqliteDatabaseR() {
        SQLiteDatabase dbR = sqliteDatabaseR.get();
        if (null != dbR || dbR.isOpen()) {
            dbR.close();
            sqliteDatabaseR.set(null);
        }
    }

    /**
     * 获得可写的SQLiteDatabase对象
     */
    public synchronized SQLiteDatabase getSqliteDatabaseW() {
        SQLiteDatabase dbW = sqliteDatabaseW.get();
        if (null == dbW || !dbW.isOpen()) {
            dbW = getWritableDatabase();
            sqliteDatabaseW.set(dbW);
        }
        return dbW;
    }

    /**
     * 关闭可写的SQLiteDatabase对象
     */
    public void closeSqliteDatabaseW() {
        SQLiteDatabase dbW = sqliteDatabaseW.get();
        if (null != dbW || dbW.isOpen()) {
            dbW.close();
            sqliteDatabaseW.set(null);
        }
    }

    /**
     * 关闭游标
     */
    public void closeCursor(Cursor c) {
        if (c != null) {
            c.close();
            c = null;
        }
    }

    /**
     * 游标 --转换为 --> Object
     *
     * @param bean
     * @param c
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    public void setObject(Object bean, Cursor c) throws IllegalArgumentException, IllegalAccessException {
        for (Field f : bean.getClass().getDeclaredFields()) {
            f.setAccessible(true);
            String columnName = f.getName();
            int columnIndex = c.getColumnIndex(columnName);
            if (columnIndex == -1) {
                continue;
            }
            if (f.getGenericType() == Long.class || f.getGenericType() == long.class) {
                f.set(bean, c.getLong(columnIndex));
            } else if (f.getGenericType() == String.class) {
                String s = c.getString(columnIndex);
                f.set(bean, TextUtils.isEmpty(s) ? "" : s);
            } else if (f.getGenericType() == Double.class || f.getGenericType() == double.class) {
                f.set(bean, c.getDouble(columnIndex));
            } else if (f.getGenericType() == Integer.class || f.getGenericType() == int.class) {
                f.set(bean, c.getInt(columnIndex));
            } else if (f.getGenericType() == Float.class || f.getGenericType() == float.class) {
                f.set(bean, c.getFloat(columnIndex));
            } else if (f.getGenericType() == Short.class || f.getGenericType() == short.class) {
                f.set(bean, c.getShort(columnIndex));
            } else if (f.getGenericType() == Byte[].class || f.getGenericType() == byte[].class) {
                f.set(bean, c.getBlob(columnIndex));
            } else { //TODO 未知类型
                f.set(bean, c.getString(columnIndex));
            }
        }
    }

    /**
     * 游标 --转换为 --> 给定类型的对象
     *
     * @param clazz
     * @param c
     * @return
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    public <T extends Serializable> T getObject(Class<T> clazz, Cursor c) throws InstantiationException, IllegalAccessException {
        T t = (T) clazz.newInstance();
        setObject(t, c);
        return t;
    }

    /**
     * 对象 --转换为 --> ContentValues
     *
     * @param bean
     * @return
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    public ContentValues getContentValues(int type, Object bean) throws IllegalArgumentException, IllegalAccessException {
        ContentValues values = new ContentValues();
        for (Field f : bean.getClass().getDeclaredFields()) {
            f.setAccessible(true);
            if (!Modifier.isStatic(f.getModifiers()) && f.getAnnotation(Except.class) == null) {
                Column c = f.getAnnotation(Column.class);
                Object value = f.get(bean);
                String name = c == null ? f.getName() : (TextUtils.isEmpty(c.columnName()) ? f.getName() : c.columnName());
                if (c != null && c.primaryKey()) {
                    if (type == TYPE_INSERT) values.put(name, (String) null);
                } else if (value instanceof Long) {
                    values.put(name, (Long) value);
                } else if (value instanceof String) {
                    values.put(name, (String) value);
                } else if (value instanceof Double) {
                    values.put(name, (Double) value);
                } else if (value instanceof Integer) {
                    values.put(name, (Integer) value);
                } else if (value instanceof Float) {
                    values.put(name, (Float) value);
                } else if (value instanceof Short) {
                    values.put(name, (Short) value);
                } else if (value instanceof Byte) {
                    values.put(name, (Byte) value);
                } else if (value instanceof Byte[]) {
                    values.put(name, (byte[]) value);
                } else { //TODO 未知类型
                    values.put(name, value != null ? value.toString() : "");
                }
            }
        }
        return values;
    }
}
